#include "SCSF.h"
#include "../../Log/NetLog.h"
#include "Poco/UUIDGenerator.h"
#include "SLLE.h"

using namespace std;

SCSF* SCSF::m_pInstance = NULL;

SCSF* SCSF::Initialize()
{

}

SCSF* SCSF::GetInstance()
{
    if (m_pInstance == NULL)
    {
        static Poco::Mutex s_mutex;
        Poco::Mutex::ScopedLock lock(s_mutex);
        if (m_pInstance == NULL)
        {
            m_pInstance = new SCSF;
        }
    }
    return m_pInstance;
}

int SCSF::Start()
{
    try
    {
        if (m_bStop == true)
        {
            //m_ready.set();
            m_thread.start(*this);
            m_bStop = false;
            //m_ready.wait();
        }
        return 0;
    }
    catch (...)
    {
        g_NetLog.Error("catched\n");
        return -1;
    }
}

int SCSF::Stop()
{
    try
    {
        if (m_bStop == false)
        {
            m_bStop = true;
            m_thread.join();
        }
        return 0;
    }
    catch (...)
    {
        g_NetLog.Error("catched\n");
        return -1;
    }
}

void SCSF::WriteHttpRequest(std::string strSYYCUUID, std::string strData)
{
    Poco::UUIDGenerator &gen = Poco::UUIDGenerator::defaultGenerator();
    SCSFData scsfData;
    scsfData.strUUID = gen.createRandom().toString();
    scsfData.strMethod = METHOD_HTTPREQUEST;
    scsfData.strSYYCData = strSYYCUUID + std::string(",") + strData;
    g_NetLog.Debug("gj write0 syyc uuid %s, method %s\n", scsfData.strUUID.c_str(), scsfData.strMethod.c_str());
    Poco::Mutex::ScopedLock lock(m_mutexWSCSFData);
    m_vectWSCSFData.push_back(scsfData);
}

void SCSF::WriteHttpResponse(std::string strSYYCUUID, std::string strData)
{
    Poco::UUIDGenerator &gen = Poco::UUIDGenerator::defaultGenerator();
    SCSFData scsfData;
    scsfData.strUUID = gen.createRandom().toString();
    scsfData.strMethod = METHOD_HTTPRESPONSE;
    scsfData.strSYYCData = strSYYCUUID + std::string(",") + strData;
    g_NetLog.Debug("gj write1 syyc uuid %s, method %s\n", scsfData.strUUID.c_str(), scsfData.strMethod.c_str());
    Poco::Mutex::ScopedLock lock(m_mutexWSCSFData);
    m_vectWSCSFData.push_back(scsfData);
}

std::string SCSF::read(std::string strSYYCUUID, std::string strMethod)
{
    if (strMethod == METHOD_HTTPREQUEST)
    {
        //g_NetLog.Debug("gj sc1 %d\n", m_vectWSCSFData.size());
        Poco::Mutex::ScopedLock  lock(m_mutexRSCSFData);
        for (size_t i = 0; i < m_vectRSCSFData.size(); ++i)
        {
            if (m_vectRSCSFData[i].strMethod == strMethod)
            {
                g_NetLog.Debug("gj method0 %s data %s\n", m_vectRSCSFData[i].strMethod.c_str(), m_vectRSCSFData[i].strSYYCData.c_str());
                string strData = m_vectRSCSFData[i].strSYYCData;
                m_vectRSCSFData.erase(m_vectRSCSFData.begin() + i);
                return strData;
            }
        }
    }
    else if (strMethod == METHOD_HTTPRESPONSE)
    {
        //g_NetLog.Debug("gj sc2 %d\n", m_vectRSCSFData.size());
        Poco::Mutex::ScopedLock lock(m_mutexRSCSFData);
        for (size_t i = 0; i < m_vectRSCSFData.size(); ++i)
        {
            if (m_vectRSCSFData[i].strMethod == strMethod && m_vectRSCSFData[i].strSYYCData.find(strSYYCUUID) != string::npos)
            {
                g_NetLog.Debug("gj method1 %s uuid [%s] data %s\n", m_vectRSCSFData[i].strMethod.c_str(), m_vectRSCSFData[i].strUUID.c_str(), m_vectRSCSFData[i].strSYYCData.c_str());
                string strData = m_vectRSCSFData[i].strSYYCData;
                m_vectRSCSFData.erase(m_vectRSCSFData.begin() + i);
                return strData;
            }
        }
    }
    return "";
}

SCSF::SCSF()
{
    m_bStop = true;
}

SCSF::~SCSF()
{

}

void SCSF::run()
{
    while (!m_vectWSCSFData.empty() || 1)
    {
        Routine();
        Poco::Thread::sleep(10);
    }
}

void SCSF::Routine()
{
    try
    {
        if (!m_vectWSCSFData.empty())
        {
            SCSFData scsfData;
            if (1)
            {
                Poco::Mutex::ScopedLock lock(m_mutexWSCSFData);
                scsfData = m_vectWSCSFData[0];
                m_vectWSCSFData.erase(m_vectWSCSFData.begin());
            }
            SLLE::GetInstance()->write(scsfData.strUUID, scsfData.strMethod, scsfData.strSYYCData);
        }
        std::string strSLLEData = SLLE::GetInstance()->read();
        if (!strSLLEData.empty())
        {
            SaveRSCSFData(strSLLEData);
        }
        Poco::Thread::sleep(1000);
    }
    catch (...)
    {
        g_NetLog.Error("catched\n");
    }
}

void SCSF::SaveRSCSFData(std::string strData)
{
    try
    {
        Poco::StringTokenizer stringToken(strData, ",", 3);
        if (stringToken.count() < 3)
        {
            return;
        }
        int iIndex0 = strData.find(string(","));
        int iIndex1 = strData.find(string(","), iIndex0 + 1);
        SCSFData scsfdata;
        scsfdata.strUUID = stringToken[0];
        scsfdata.strMethod = stringToken[1];
        scsfdata.strSYYCData = strData.substr(iIndex1 + 1);
        g_NetLog.Debug("gj save method %s uuid %s, data [%s]\n", scsfdata.strMethod.c_str(), scsfdata.strUUID.c_str(), scsfdata.strSYYCData.c_str());
        Poco::Mutex::ScopedLock lock(m_mutexRSCSFData);
        m_vectRSCSFData.push_back(scsfdata);
    }
    catch (...)
    {
        g_NetLog.Error("catched\n");
    }
}

